// RobotController.h
#pragma once
#include <QObject>
#include <QThread>
#include <QMutex>
#include "SCStatusTcp.h"
#include "RequestManager.h"
#include "StatusWorker.h"

struct PositionData {
    double x = 0.0;
    double y = 0.0;
    double angle = 0.0;
};

class StatusWorker;
class RobotController : public QObject {
    Q_OBJECT
    Q_PROPERTY(bool connected READ isConnected NOTIFY connectionChanged)
public:
    explicit RobotController(QObject *parent = nullptr);
    ~RobotController();
    Q_INVOKABLE void connectRobot(const QString &seerIP,const QString &robotIP);
    Q_INVOKABLE void disconnectRobot();
    Q_INVOKABLE bool isConnected() const;
    
    // QML 可调用的命令
    Q_INVOKABLE void relocation(const int cmdId); // 重定位
    Q_INVOKABLE void runGoal(const QString &start, const QString &end);
    Q_INVOKABLE void getRobotBattery(int cmdId);
    Q_INVOKABLE void getRobotPosition(int cmdId);
    Q_INVOKABLE void getRobotNavigationalState(int cmdId);
    Q_INVOKABLE void getMapSiteInformation(int cmdId);      //获取当前地图中站点信息
    Q_INVOKABLE void softEmergencyStop(int cmdId, bool status = true); // 软急停
    Q_INVOKABLE void moveRobot(double dist, double vx, double vy, int mode, int cmdId); // 平动控制
    Q_INVOKABLE void rotateRobot(double angle, double vw, int mode, int cmdId); // 转动控制
    Q_INVOKABLE void setParameters(const QString robotId);
    Q_INVOKABLE void getCurrentMap();
    Q_INVOKABLE void getControlAuthority(int cmdId); // 查询控制权
    Q_INVOKABLE void getPathBetweenTwoPoint(int cmdId); //查询任意两点之间的路径
    Q_INVOKABLE QString getCurrentMapName() const { return m_currentMapName; }
    Q_INVOKABLE void acquireControlAuthority(const QString& nickName, int cmdId); // 抢占控制权
    Q_INVOKABLE void releaseControlAuthority(int cmdId); // 释放控制权
    Q_INVOKABLE void reposition(bool isAuto, double x, double y, double angle, int cmdId); // 重定位
    Q_INVOKABLE void startLoopMoveRobot(double vx, double vy, double rad, int cmdId); // 开环运动控制
    Q_INVOKABLE void stopLoopMoveRobot(int cmdId); // 停止开环运动
    Q_INVOKABLE void executePathNavigation(const QString& pathData, int cmdId); // 指定路径导航
    Q_INVOKABLE void relocateAndNavigate(const QString& pathData, int relocateCmdId, int navigateCmdId); //重定位成功后执行指定路径导航
    Q_INVOKABLE void pauseNavigation(int cmdId);        // 暂停导航
    Q_INVOKABLE void resumeNavigation(int cmdId);       // 恢复导航
    Q_INVOKABLE void cancelNavigation(int cmdId);       // 取消导航
    Q_INVOKABLE void getRobotAlarmStatus(int cmdId);    // 获取机器人报警状态
    Q_INVOKABLE void clearRobotAlarms(int cmdId);       // 清除机器人当前所有报错
    Q_INVOKABLE void downloadLogFiles(int cmdId);       // 下载日志文件
    Q_INVOKABLE void cleanClientLogFiles(int cmdId);          // 清理日志文件
    Q_INVOKABLE void executeGenericCommand(int cmdId, const QByteArray& jsonData,int socketType = 0); // 通用命令接口
    void downloadMap(const QString& mapName);
    void handleOperationCompleted(int cmdId, bool success, const QByteArray& data);

signals:
    void connectionChanged(bool connected);
    void statusUpdated(const QVariantMap &data);
    void operationCompleted(int cmdId, bool success);
    void batteryUpdated(double level);                              //更新电池信号
    void positionUpdated(double x, double y, double angle);         //更新位置信号
    void navigationStateUpdated(QString state, QString target);     //更新导航状态信号
    void controlAuthorityUpdated(bool hasAuthority, QString owner); // 控制权状态更新信号
    void mapStationInformationUpdated(const QString& stationData);  // 地图站点信息更新信号
    void robotStatus(const QString status);                         //导航错误信号
    void robotAlarmStatusUpdated(const QString& statusJson);        //机器人报警状态更新信号
    void robotPathBetweenTwoPointUpdated(const QString& pathData);  //更新任意两点之间的路径
    
    private:
    SCStatusTcp m_ctrlSocket;       //控制
    SCStatusTcp m_naviSocket;       //导航
    SCStatusTcp m_statSocket;       //状态查询
    SCStatusTcp m_otherSocket;      //软急停
    SCStatusTcp m_confSocket;       //配置
    SCStatusTcp m_logsSocket;       //RMSClient日志下载端口
    RequestManager m_requestManager;
    static const QHash<int, QString> stateMap;  //导航状态映射

    double m_battery = 0.0;                     // 电量
    PositionData m_position;                    // 位置
    QString m_navState;                         // 导航状态
    QString m_currentTarget;
    QString m_robotId;                          // 机器人ID
    QString m_currentMapName;                   // 当前地图名称

    QThread m_workerThread;
    StatusWorker* m_worker;
    mutable QMutex m_dataMutex;
};